package com.wuyan.web.auth.api;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.wuyan.web.auth.entity.PubAccount;
import com.wuyan.web.auth.entity.PubConfig;
import com.wuyan.web.auth.entity.PubUser;
import com.wuyan.web.auth.helper.AuthHelper;
import com.wuyan.web.auth.service.LoginService;
import com.wuyan.web.auth.service.PubConfigService;
import com.wuyan.web.base.helper.PubConfigHelper;
import com.wuyan.web.base.helper.auth.LoginInfo;
import com.wuyan.web.auth.helper.wx.AccessToken;
import com.wuyan.web.auth.helper.wx.Userinfo;
import com.wuyan.web.auth.service.api.WxAuthApiService;
import com.wuyan.web.base.helper.rep.RepBody;
import com.wuyan.web.base.helper.rep.RepCodeEnum;
import com.wuyan.web.base.helper.rep.RepHelper;
import com.wuyan.web.base.helper.rep.RepPageData;
import com.wuyan.web.base.helper.req.CustomQueryHelper;
import com.wuyan.web.base.helper.req.CustomQueryParams;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

/**
 * 微信登录授权接口
 */

@Slf4j
@RestController
@RequestMapping("/api")
public class WxAuthApi implements RepHelper {
    private static final String CONFIG_TYPE_WX_NAME = "wx";
    private static final String CONFIG_KEY_WX_APPID_NAME = "appid";
    private static final String CONFIG_KEY_WX_SECRET_NAME = "secret";

    @Autowired
    private WxAuthApiService wxAuthApiService;

    @Autowired
    private AuthHelper authHelper;

    @Autowired
    private PubConfigService pubConfigService;

    @Autowired
    private LoginService loginService;

    @Value(value = "${wuyan.wx.app-id}")
    private String appId;

    @Value(value = "${wuyan.wx.secret}")
    private String secret;

    private List<PubConfig> wxConfig;

    /**
     * 微信web登陆，基于code
     *
     * @param code  临时授权信息
     * @param state 跳转时携带的参数
     * @return RepBody<LoginInfo>
     * @throws JsonProcessingException JSON格式化错误
     */
    @GetMapping("/login-wx-web")
    public RepBody<LoginInfo> loginWxWeb(@RequestParam(value = "code", defaultValue = "") String code,
                                         @RequestParam(value = "state", defaultValue = "") String state,
                                         HttpServletRequest request,
                                         HttpServletResponse response)
            throws Exception {
        this.wxConfig = getWxConfig();
        String appid = getConfigValue(CONFIG_KEY_WX_APPID_NAME);
        String secret = getConfigValue(CONFIG_KEY_WX_SECRET_NAME);

        AccessToken accessToken = wxAuthApiService.getAccessToken(appid, secret, code, "authorization_code");
        if (null != accessToken.getErrcode()) {
            return error(RepCodeEnum.ERR_LOGIN);
        }

        Userinfo userinfo = wxAuthApiService.getUserinfo(accessToken.getAccess_token(), accessToken.getOpenid(), "zh_CN");
        if (null != userinfo.getErrcode()) {
            return error(RepCodeEnum.ERR_LOGIN);
        }

        PubUser pubUser;
        PubAccount pubAccount = loginService.getAccountByWx(accessToken.getOpenid(), userinfo.getUnionid());

        // 账户不存在时根据微信得到得用户信息进行创建
        if (null == pubAccount) {
            pubAccount = loginService.createAccount(accessToken, userinfo);
            pubUser = loginService.createUser(pubAccount.getId(), userinfo);
        } else {
            if(pubAccount.getStatus() != 1){
                return error(RepCodeEnum.ERR_LOGIN_STATUS);
            }

            pubUser = loginService.getUser(pubAccount.getId());
        }

        LoginInfo loginInfo = loginService.saveLoginInfo(request, response, pubAccount, pubUser);
        return ok(loginInfo);
    }

    /**
     * 获取指定配置得值
     *
     * @param key 键
     * @return String
     */
    private String getConfigValue(String key) {
        for (PubConfig pubConfig : wxConfig) {
            if (pubConfig.getCfgKey().equals(key)) {
                return pubConfig.getCfgValue();
            }
        }

        if (CONFIG_KEY_WX_APPID_NAME.equals(key)) {
            return this.appId;
        }

        if (CONFIG_KEY_WX_SECRET_NAME.equals(key)) {
            return this.secret;
        }

        return "";
    }

    /**
     * 获取微信相关配置信息
     *
     * @return List<PubConfig>
     */
    private List<PubConfig> getWxConfig() throws ClassNotFoundException, NoSuchMethodException,
            InvocationTargetException, InstantiationException, IllegalAccessException {
        List<CustomQueryParams> params = PubConfigHelper.newParams(CONFIG_TYPE_WX_NAME, null);
        CustomQueryHelper<PubConfig> queryHelper = CustomQueryHelper.init(PubConfig.class, params, new ArrayList<>());

        RepPageData<PubConfig> data = pubConfigService.page(
                queryHelper.getPredicates(),
                queryHelper.getOrders(),
                false,
                0,
                0
        );

        List<PubConfig> list = data.getList();

        if (null == list || list.isEmpty()) {
            return new ArrayList<>();
        }

        return null == data.getList() ? new ArrayList<>() : data.getList();
    }
}
